package cn.hinglo.permission.service;

import cn.hinglo.common.plugin.quartz.QuartzManager;
import cn.hinglo.common.util.SysCommonKit;
import cn.hinglo.permission.model.JobBean;
import cn.hutool.core.util.StrUtil;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.SqlPara;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.quartz.Job;

import java.util.Date;
import java.util.Map;

/**
 * 定是任务服务层
 *
 * @author Hinglo
 */
@Slf4j
public class QuartzService {

    /***
     * 该任务的状态是立马运行就添加到定是任务调度器中
     */
    private static final Integer RUN = 1;
    private static final Integer PAUSE = 2;

    private QuartzManager quartzManager = QuartzManager.getSingleton();

    /***
     * 添加作业
     * @param job 任务
     * @return 返回添加是否成功，需要开始事物，数据库与调度器都必须添加成功
     */
    public boolean addTaskService(JobBean job) {
        job.setGmtModified(new Date()).setGmtCreate(new Date());
        return Db.tx(() -> {
            if (job.save()) {
                return !job.getStatus().equals(RUN) || quartzManager.addorUpdateJob(job);
            }
            return false;
        });
    }

    /***
     * 恢复作业
     * @param id 任务ID
     * @return 返回任务恢复状态
     */
    public boolean resumeJobService(Integer id) {
        JobBean job = JobBean.dao.findById(id);
        if (job != null && job.getStatus().equals(PAUSE)) {
            job.setStatus(RUN).setGmtModified(new Date());
            return Db.tx(() -> quartzManager.resumeJob(job) && job.update());
        }
        return false;
    }

    /**
     * 暂停作业
     *
     * @param id 任务的ID
     * @return 返回暂停结果状态
     */
    public boolean pauseJobService(Integer id) {
        JobBean job = JobBean.dao.findById(id);
        if (job != null && job.getStatus().equals(RUN)) {
            job.setStatus(PAUSE).setGmtModified(new Date());
            return Db.tx(() -> quartzManager.pauseJob(job) && job.update());
        }
        return false;
    }

    /***
     * 根据指定的定时任务ID删除定时任务,从数据库中与定时任务调度器中删除任务
     * @param id 定时任务ID
     * @return 返回结果
     */
    public boolean deleteJobService(Integer id) {
        JobBean job = JobBean.dao.findById(id);
        if (job != null) {
            return Db.tx(() -> quartzManager.deleteJob(job) && job.delete());
        }
        return false;
    }

    /***
     * 更新定时任务，值更新表达式，
     * @param id 任务编号
     * @param corn 表达式
     * @return 返回是否更新成功
     */
    public boolean updateService(Integer id, String corn) {
        if (id == null || StrUtil.isBlank(corn)) {
            throw new RuntimeException("定时任务ID或者表达式不能为空");
        }
        JobBean job = JobBean.dao.findById(id);
        if (job == null) {
            throw new RuntimeException("定时任务不存在");
        }
        if (job.getStatus().equals(RUN)) {
            throw new RuntimeException("运行中的定时任务无法更新，请暂停任务后开始更新");
        }
        job.setGmtModified(new Date()).setGmtCreate(new Date());
        job.setCron(corn);
        return Db.tx(() -> quartzManager.addorUpdateJob(job) && job.update());
    }

    /***
     * 定时任务列表
     * @param size size
     * @param page page
     * @return 返回分页结果
     */
    public Map<String, Object> listService(Integer page, Integer size) {
        SqlPara sql = Db.getSqlPara("job.all");
        Page<JobBean> paginate = JobBean.dao.paginate(page, size, sql);
        return SysCommonKit.pageKit(paginate.getTotalRow(), SysCommonKit.modelToMapKit(paginate.getList()));
    }

    /***
     * 手动触发执行定时任务
     * @param id 任务编号
     * @return 返回结果
     */
    @SneakyThrows
    public boolean execute(Integer id) {
        try {
            JobBean job = JobBean.dao.findById(id);
            String clazz = job.getClazz();
            Class<?> userClass = Class.forName(clazz);
            Job job1 = (Job) userClass.newInstance();
            job1.execute(null);
        } catch (Exception e) {
            log.error("手动触发定时任务发生异常，异常信息为：", e);
            return false;
        }
        return true;
    }


}
